package com.zmn.oms.task.listener;

import com.alibaba.fastjson.JSON;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.manager.mq.annotation.AliyunMQHandler;
import com.zmn.manager.mq.annotation.AliyunMQListener;
import com.zmn.manager.redis.RedisManager;
import com.zmn.oms.business.interfaces.messageV1.wechat.MessageWeChatTemplateService;
import com.zmn.oms.business.interfaces.work.OrderWorkBService;
import com.zmn.oms.common.constant.MessageQueueTagConsts;
import com.zmn.oms.common.constant.OrderPayConsts;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.common.constant.RedisKeyConsts;
import com.zmn.oms.common.dro.orderpay.OrderPayResultDRO;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.model.dto.work.masterwork.CompleteDTO;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.zmn.business.interfaces.work.ZsOrderWorkAmountBService;
import com.zmn.oms.zmn.business.interfaces.work.autoflow.WorkFlowContextBService;
import com.zmn.oms.zmn.business.interfaces.work.orderpay.OrderPayResultBService;
import com.zmn.oms.zmn.business.interfaces.work.orderpay.ZsOrderPayBService;
import com.zmn.oms.zmn.normal.business.interfaces.work.masterwork.ZsNormalMasterWorkBService;
import com.zmn.pay.common.constant.PayConsts;
import com.zmn.pay.gateway.common.model.dro.PayResultDRO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Objects;

/**
 * @author ：SongWeidong
 * @date ：2021/4/8 18:18
 * @description：支付监听
 */
@Slf4j
@AliyunMQListener(topic = "${spring.mq.topic.oms}")
@Component
public class OrderMOSPayListener {
    @Autowired
    private ZsOrderWorkAmountBService zsOrderWorkAmountBService;
    @Autowired
    private ZsNormalMasterWorkBService zsNormalMasterWorkBService;
    @Autowired
    private OrderWorkBService orderWorkBService;
    @Autowired
    private OrderPayResultBService orderPayResultBService;
    @Autowired
    private WorkFlowContextBService workFlowContextBService;
    @Autowired
    private ZsOrderPayBService zsOrderPayBService;
    @Autowired
    private OrderWorkService orderWorkService;
    @Autowired
    private MessageWeChatTemplateService messageWeChatTemplateService;
    @Autowired
    private RedisManager redisManager;


    @AliyunMQHandler(tags = MessageQueueTagConsts.OMS_ORDERPAY)
    public void payResult(String message) {
        log.info("订单支付监听：{}", message);
        PayResultDRO payResultDRO = JSON.parseObject(message,PayResultDRO.class);

        // 支付模型转化成订单支付模型
        OrderPayResultDRO orderPayResultDRO = orderPayResultBService.convertOrderPayResult(payResultDRO);
        // 优惠支付
        if (Objects.equals(orderPayResultDRO.getPayChannelId(), PayConsts.PAY_CHANNEL_PLATFORM_DISCOUNT)) {
            zsOrderWorkAmountBService.updateDiscountAmountPayResult(orderPayResultDRO);
            return;
        }
        Integer amountType = orderPayResultDRO.getAmountType();
        if (NumberUtil.isNullOrZero(amountType)) {
            log.error("未处理的支付结果{}", orderPayResultDRO);
            return;
        }

        // 更新优惠券信息，如果有的话
        try {
            zsOrderWorkAmountBService.updatePayDiscountPayResult(orderPayResultDRO);
        } catch (Exception e) {
            log.error(String.format("订单[%s]更新支付优惠失败", orderPayResultDRO.getOrderId()), e);
        }

        switch (amountType.intValue()) {
            // 平台预收款
            case OrderPayConsts.ORDER_PAY_PREPAY:
                zsOrderWorkAmountBService.updatePrepaidAmountPayResult(orderPayResultDRO);
                break;
            // 渠道预收款
            case OrderPayConsts.ORDER_PAY_CHANNEL_PREPAY:
                zsOrderWorkAmountBService.updateChannelPrepaidAmountPayResult(orderPayResultDRO);
                break;
            // 定金
            case OrderPayConsts.ORDER_PAY_DEPOSIT:
                zsOrderWorkAmountBService.updateDepositAmountPayResult(orderPayResultDRO);
                break;
            // 工程师收款
            case OrderPayConsts.ORDER_PAY_MASTER:
                this.updateMasterAmount(orderPayResultDRO);
                break;
            // 进度款
            case OrderPayConsts.ORDER_PAY_PROGRESS:
                zsOrderWorkAmountBService.updateProgressAmountPayResult(orderPayResultDRO);
                break;
            default:
                log.error("未知金额类型[{}]", amountType);
                break;
        }

        try {
            String redisKey = String.format(RedisKeyConsts.ORDER_CANCELED_REFUND_KEY, orderPayResultDRO.getOrderId());
            if (redisManager.exists(redisKey)) {
                OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderPayResultDRO.getOrderId(), orderPayResultDRO.getWorkId());
                if (Objects.equals(orderWork.getStatus(), OrderStatusConsts.ORDER_STATUS_CANCEL)) {
                    zsOrderPayBService.compensateRefund(orderPayResultDRO);
                }
            }
        } catch (OmsBaseException e) {
            log.error("已取消订单退款失败", e);
        }
    }

    /**
     * 更新工程师收款
     * @param orderPayResultDRO
     */
    private void updateMasterAmount(OrderPayResultDRO orderPayResultDRO) {
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderPayResultDRO.getOrderId(), orderPayResultDRO.getOrderId());

        // 校验支付用户 是否一致
        try {
            orderWorkBService.checkPayUserId(orderPayResultDRO, orderWork.getPlat(), orderWork.getReceiveEntranceId());
        } catch (Exception e) {
            log.error("工单支付后，检测用户异常");
            log.error(e.getMessage(), e);
        }

        // 更新工程师收款
        zsOrderWorkAmountBService.updateMasterAmountPayResult(orderPayResultDRO);
        // 更新完成
        CompleteDTO completeDTO = BeanMapper.map(orderPayResultDRO, CompleteDTO.class);
        try {
            zsNormalMasterWorkBService.completeOrder(completeDTO);
        } catch (Exception e) {
            log.error("[{}]工单支付后，自动完成异常", orderPayResultDRO.getWorkId());
            log.error(e.getMessage(), e);
            return;
        }
        workFlowContextBService.asyncAutoFlow(orderPayResultDRO.getOrderId(), orderPayResultDRO.getWorkId());

        try {
            log.info("发送思域流量处理：orderPayResultDRO={}", JSON.toJSONString(orderPayResultDRO));
            // 公众号支付才发送私域流量消息   微信=2，  银联中信= 22
            if (StringUtils.isNotBlank(orderPayResultDRO.getAppBizSubNo()) &&
                    Objects.equals(PayConsts.PAY_TYPE_SERVNUMBERPAY, orderPayResultDRO.getPayType()) &&
                    (Objects.equals(PayConsts.PAY_CHANNEL_PLATFORM_WEIXINPAY, orderPayResultDRO.getPayChannelId()) ||
                            Objects.equals(PayConsts.PAY_CHANNEL_THIRD_ECITIC, orderPayResultDRO.getPayChannelId()))) {
                int index = orderPayResultDRO.getAppBizSubNo().indexOf("-");
                String openId = orderPayResultDRO.getAppBizSubNo().substring(index+1);

                if (index > 0 && StringUtil.isNotBlank(openId)) {
                    messageWeChatTemplateService.sendWeChatPrivateTrafficMsg(orderPayResultDRO.getOrderId(),
                            orderWork.getPlatWork(), orderWork.getChannelId(), orderWork.getUserId(), openId);
                }
            }
        } catch (Exception ex) {
            log.error("[{}]工单尾款支付后，通知 saas 失败", orderPayResultDRO.getWorkId());
        }
    }
}
